#include "emetteur.h"
#include "commun/erreur.h"
#include "reseau.h"
#include <cassert>

/**
 * Construit un émetteur et alloue un paquet UDP.
 */
emetteur_reseau::emetteur_reseau(TCPsocket &chaussette_tcp, 
								 UDPsocket &chaussette_udp, 
								 IPaddress &adresse_udp) throw() 
								:	chaussette_tcp_(chaussette_tcp), 
									chaussette_udp_(chaussette_udp)  {
	adresse_udp_.host = adresse_udp.host;
	adresse_udp_.port = adresse_udp.port;
								
	paquet_ = SDLNet_AllocPacket(TAILLE_BUFFER);
	if(!paquet_)
		throw une_erreur<allocation_paquet>();
										
	
	paquet_->address.host = adresse_udp_.host;
	paquet_->address.port = adresse_udp_.port;
}

/**
 * Envoie les données par TCP.
 */
void emetteur_reseau::envoyer_tcp(const char *srcbuf, int taille) {
	char buffer[TAILLE_BUFFER];
	assert(taille <= TAILLE_BUFFER);
	std::copy(srcbuf, srcbuf+taille, buffer);
	if(SDLNet_TCP_Send(chaussette_tcp_, reinterpret_cast<void*>(buffer), TAILLE_BUFFER) < TAILLE_BUFFER)
		throw une_erreur<envoi_socket>();
}

/**
 * Envoie la chaîne de caractères par TCP.
 */
void emetteur_reseau::envoyer_tcp(std::string s) {
	envoyer_tcp(s.c_str(), s.size()+1);
}

/**
 * Envoie les données par UDP.
 */
void emetteur_reseau::envoyer_udp(void *data, int lng) {
	paquet_->len = lng;
	std::copy(reinterpret_cast<Uint8*>(data), reinterpret_cast<Uint8*>(data)+lng, paquet_->data);
	
	if(SDLNet_UDP_Send(chaussette_udp_, -1, paquet_) < 1)
		throw new une_erreur<envoi_socket>;
}

/**
 * Envoie l'instantané du piano par UDP.
 */
void emetteur_reseau::envoyer_udp(instantane_du_piano &c) {
	SDLNet_Write32(c.timestamp(), paquet_->data + instantane_du_piano::nb_octets);
	paquet_->len = sizeof(temps::type_temps) + instantane_du_piano::nb_octets;
	
	c.remplir(paquet_->data);
	
	if(SDLNet_UDP_Send(chaussette_udp_, -1, paquet_) < 1)
		throw new une_erreur<envoi_socket>;
}
